package com.magenta.maxoptra.geocoding.geoinformsputnik;

import com4j.Holder;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * User: Zlygostev
 * Date: 18.04.12
 * Time: 14:42
 */
public class GeoSamaraCRSConverter {

    private static Map<String, IGeoTransform> transformsMap = new HashMap<String, IGeoTransform>();
    private static Map<GeoPosition, double[]> geoPositionMap = new HashMap<GeoPosition, double[]>();
    private static String settings;

    public static final String SYSTEM_NAME = "rosinkas";

    private static final String JBOSS_CONF_DIR_PROPERTY = "jboss.server.config.url";
    private static final String GEO_TRANSFORMER = "geotransform.xml";

    private static IGeoTransform getTransform(String src, String dest) {
        String key = src + "->" + dest;
        IGeoTransform transform = transformsMap.get(key);
        if (transform == null) {
            transform = ClassFactory.createGeoTransform();
            transform.initByXmlFile(getJBossConfPath() + "/" + GEO_TRANSFORMER);
            //transform.initByXmlString(readString(GeoSamaraCRSConverter.class, "/geosamara/geotransform.xml"));
            transform.sourceSys(src);
            transform.destSys(dest);
            transformsMap.put(key, transform);
        }
        return transform;
    }

    public static String readString(Class aClass, String resourceName) {
        final InputStream in = aClass.getResourceAsStream(resourceName);
        if (in == null) {
            throw new IllegalArgumentException("sql file not found: " + resourceName);
        }
        final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        try {
            final StringBuffer buf = new StringBuffer();
            while (reader.ready()) {
                buf.append(reader.readLine());
                buf.append("\n");
            }
            return buf.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                in.close();
                reader.close();
            } catch (IOException e) {
                //noinspection ThrowFromFinallyBlock
                throw new RuntimeException(e);
            }
        }
    }


    private static boolean isJbossMode() {
        return System.getProperty("jboss.home.dir") != null;
    }

    public static String getAppDataStorageLocation() {
        String appDataFilePath = isJbossMode() ? "c:/temp" : System.getenv("APPDATA");
        if (appDataFilePath == null) {
            throw new RuntimeException("System environment variable 'APPDATA' is not set");
        }
        String companyDir = "Magenta";
        String project = SYSTEM_NAME;
        String s = System.getProperty("file.separator");
        String storageLocation = appDataFilePath + s + companyDir + s + project;
        if (!(new File(storageLocation).exists())) {
            File dir = new File(appDataFilePath + s + companyDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            dir = new File(appDataFilePath + s + companyDir + s + project);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
        return storageLocation;
    }


    /**
     * @param x geosamara coordinate
     * @param y geosamara coordinate
     * @return latitude longitude
     */
    public static GeoPosition convert(double x, double y) {
        return convert(x, y, "SamObl_Transformed");
    }

    public static GeoPosition convert(double x, double y, String transform) {
        IGeoTransform geoTransform = getTransform(transform, "WGS84");
        double src_Z = 0;

        Holder<Double> dst_X = new Holder<Double>();
        Holder<Double> dst_Y = new Holder<Double>();
        Holder<Double> dst_Z = new Holder<Double>();

        geoTransform.transformOnePoint(x, y, src_Z, dst_X, dst_Y, dst_Z);
        return new GeoPosition(dst_X.value, dst_Y.value);
    }

    /**
     * @param geoPosition latitude longitude
     * @return geosamara coordinates
     */
    public static double[] convert(GeoPosition geoPosition) {
        double[] doubles = geoPositionMap.get(geoPosition);
        if (doubles != null) {
            return doubles;
        }
        IGeoTransform geoTransform = getTransform("WGS84", "SamObl_Transformed");
        double src_X = geoPosition.getLatitude();
        double src_Y = geoPosition.getLongitude();
        double src_Z = 0;

        Holder<Double> dst_X = new Holder<Double>();
        Holder<Double> dst_Y = new Holder<Double>();
        Holder<Double> dst_Z = new Holder<Double>();

        geoTransform.transformOnePoint(src_X, src_Y, src_Z, dst_X, dst_Y, dst_Z);

        doubles = new double[]{dst_X.value, dst_Y.value};
        geoPositionMap.put(geoPosition, doubles);
        return doubles;
    }

    private static String getJBossConfPath() {
        String jbossConfDir = System.getProperty(JBOSS_CONF_DIR_PROPERTY);
        if (jbossConfDir != null) {
            jbossConfDir = jbossConfDir.replaceAll("\\\\", "/").replace("file:/","");
        }
        return jbossConfDir;
    }


    public static void main(String[] args) throws InterruptedException {

//        String src = "SamObl_Transformed";
//        String dest = "WGS84";
//        double x = 9545424.01235449;
//        double y = 5999142.25524284;

        String src = "WGS84";
        String dest = "SamObl_Transformed";

        //ne: 54.73390667909835 52.69064996534562
        //53.20772352587169  50.16672527750493
        double x = 53.20772352587169;
        double y = 50.16672527750493;
        double z = 0;

        IGeoTransform transform = ClassFactory.createGeoTransform();
        //transform.initByXmlFile(GeoSamaraCRSConverter.class.getResource("/geosamara/geotransform.xml").getFile());
        transform.initByXmlFile("E:\\work\\Maxoptra\\GT\\4.0\\externals\\gis-services\\geoprovider-geo-inform-sputnik\\jboss\\server\\default\\conf\\geotransform.xml");
        //transform.initByXmlFile(getJBossConfPath() + "/" + GEO_TRANSFORMER);
        transform.sourceSys(src);
        transform.destSys(dest);

        Holder<Double> dst_X = new Holder<Double>();
        Holder<Double> dst_Y = new Holder<Double>();
        Holder<Double> dst_Z = new Holder<Double>();

        transform.transformOnePoint(x, y, z, dst_X, dst_Y, dst_Z);
        System.out.println(dst_X.value + ";" + dst_Y.value+ ";" + dst_Z.value);
    }
}